package com.tristia.resources.impl;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.annotation.Resource;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.sun.jersey.api.NotFoundException;
import com.tristia.dao.GenericDao;
import com.tristia.entity.State;
import com.tristia.entity.States;
import com.tristia.entity.util.ItemInfoIdComparator;

@Component
@Path("/states")
@Scope("request")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML })
public class StatesResWs {
	@Resource
	GenericDao<State, Long> stateDao;
	@Context 
	UriInfo ui;
	@Context
	Request request;
	private Logger log = Logger.getLogger(this.getClass());
	
	@GET
	public States getStates() {
		log.info("getStates entered");
		States states = new States();
		Set<State> stateTree = new TreeSet<State>(new ItemInfoIdComparator("ACS"));
		stateTree.addAll(stateDao.getAll());
		states.setStates(stateTree);
		log.info("Sending: \n\n" + states.toString() + "\n\n");
		return states;
	}
	
	@GET
	@Path("/{stateId}")
	public State getState(@PathParam("stateId") long stateId) {
		log.info("getState entered");
		State state = stateDao.get(stateId);
		if (state == null)throw new NotFoundException("State not found");
		log.info("Sending: \n\n" + state.toString() + "\n\n");
		return state;
	}
	
	@PUT
	public Response updateState(@QueryParam("id") String id,
			@QueryParam("rating") String rating) {
		log.info("updateState entered");
		log.info("rating: " + rating);
		log.info("id : " + id);
		
		Response r;
//		URI uri =  ui.getAbsolutePath();
		if (StringUtils.hasText(id)) {
			log.info("It has an ID");
			long idd = Long.parseLong(id);
			boolean stateExists = stateDao.exists(idd);
			if (stateExists == true) {
				log.info("We found the state with that id");
				State state = stateDao.get(idd);
				state.setRating(Float.parseFloat(rating));
				stateDao.save(state);
				log.info("Updated successfully");
//				r = Response.created(uri).build();
				r = Response.ok(state).build();
			} else {
				log.info("We do not found the state with that id");
				r = Response.noContent().build();
			}
		} else {
			log.info("It doesn't have an ID");
			log.info("Put the new state");
			State state = new State();
			state.setRating(Float.parseFloat(rating));
			stateDao.save(state);
			log.info("Updated successfully");
			r = Response.ok(state).build();
		}
		return r;
	}
	
	@POST
	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_XML })
	public Response addState(@QueryParam("rating") String rating) {
		log.info("addState entered");
		log.info("rating: " + rating);

//		SuccessInfo successInfo = new SuccessInfo();
		Response r;
		State state = new State();
		state.setRating(Float.parseFloat(rating));
		stateDao.save(state);
		log.info("Updated successfully");
		r = Response.ok(state).build();
//		successInfo.getSuccesses().add("Created successfully");
		return r;
	}
	
	@DELETE
	@Path("/{stateId}")
	public void deleteState(@PathParam("stateId") String stateId) {
		if(stateId!=null) {
			deleteStateById(stateId);
		}
		
		MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
		List<String> ids = queryParams.get("stateId");
		if(ids == null) {
			log.info("\n\nThe ids is null");
		} else {
			for (String currentid : ids) {
				deleteStateById(currentid);
			}
		}
	}

	private void deleteStateById(String id) {
		log.info("Delete Id: " + id);
		State state = stateDao.get(Long.parseLong(id));
		if (state == null) {
			log.info("Null was returned for ID: " + id);
		} else {
			stateDao.remove(Long.parseLong(id));
			log.info("Deleted the CD with ID:" + id);
		}
	}

}
